<?php
require_once APPLICATION_PATH . '/controllers/LoginController.php';

/**
 * mail控制器
 * @author Administrator
 *
 */
class MailController extends LoginController
{

    public function init()
    {
        parent::init();
    }

    public function indexAction()
    {
    	$this->view->title = "电子邮箱";
    }
    
    /**
     * 收件列表
     */
    public function inboxAction()
    {
        if($this->getRequest()->isPost()){
        	$userM = new Application_Model_DbTable_Mailinbox();
        	$pageM = $this->_helper->Flexgp();
        	$where = " `deleted` = 0 ";
			$data = $userM->jqfetchAll($pageM,$where);
			foreach ($data["data"] as &$d){
				$d["create_time"] = date("Y-m-d H:i:s",$d["create_time"]);
				$d["send_time"] = empty($d["send_time"])?"":date("Y-m-d H:i:s",$d["send_time"]);
				$d["state"] = ($this->_user->type == 0)?$d["state_admin"]:$d["state_user"];
			}
			$data = $this->view->jqflexgrid($data,"id");
		    $this->_helper->json($data); 
        }else{
        	//获取页面
    		die("404");
        }
    }
    
    /**
     * 发件列表
     */
    public function outboxAction()
    {
        if($this->getRequest()->isPost()){
        	$mailM = new Application_Model_DbTable_Mailoutbox();
        	try{
        		$mailM->delete(" `edite_status` = '-1' ");
        	}catch (Exception $e){}
        	$pageM = $this->_helper->Flexgp();
        	$where = " `deleted` = 0 ";
			$data = $mailM->jqfetchAll($pageM,$where);
			foreach ($data["data"] as &$d){
				$d["create_time"] = date("Y-m-d H:i:s",$d["create_time"]);
				$d["send_time"] = empty($d["send_time"])?"":date("Y-m-d H:i:s",$d["send_time"]);
				$d["state"] = ($this->_user->type == 0)?$d["state_admin"]:$d["state_user"];
			}
			$data = $this->view->jqflexgrid($data,"id");
		    $this->_helper->json($data); 
        }else{
        	//获取页面
    		die("404");
        }
    }
        
    /**
     * 回收站列表
     */
    public function recycleboxAction()
    {
        if($this->getRequest()->isPost()){
        	$userM = new Application_Model_DbTable_Mailinbox();
        	$pageM = $this->_helper->Flexgp();
        	$where = " `deleted` = 1 ";
			$data = $userM->jqfetchAll($pageM,$where);
			foreach ($data["data"] as &$d){
				$d["create_time"] = date("Y-m-d H:i:s",$d["create_time"]);
				$d["state"] = ($this->_user->type == 0)?$d["state_admin"]:$d["state_user"];
			}
			$data = $this->view->jqflexgrid($data,"id");
		    $this->_helper->json($data); 
        }else{
        	//获取页面
    		die("404");
        }
    }

    /**
     * 设置读取状态
     */
    public function setstateAction()
    {
    	if($this->getRequest()->isPost()){
	    	$state 	= intval($this->getRequest()->getParam("state",0));
	    	$id 	= intval($this->getRequest()->getParam("id",0));
	    	
	    	$redata = array(
	    		"status" => 0,
	    		"msg"	 => "错误"
	    	);
	    	
	    	if($id != 0){    		
	        	$userM = new Application_Model_DbTable_Mailinbox();
	    		$stateField = ($this->_user->type == 0)?"state_admin":"state_user";
	    		$data = array(
	    			$stateField => $state
	    		);
	    		try{
		    		$userM->update($data, " `id` = {$id} ");
	    			$redata["status"] = 1;
	    			$redata["msg"] = "成功";		    		
	    		}catch (Exception $e){
	    			$redata["msg"] = "数据库错误 ： " . $e->getMessage();
	    		}
	    	}else {
	    		$redata["msg"] = "参数错误！";
	    	}
	    	$this->_helper->json($redata);
    	}else{
    		die("404");
    	}
    	
    	
    }
    
    /**
     * 设置负责人
     */
    public function setuserAction()
    {
    	$id	   = intval($this->getRequest()->getParam("id",0));
    	$formM = new Application_Form_Base("mail_setuser");
    	$userM = new Application_Model_DbTable_User();
    	$userL = $userM->fetchAll(" `type` <> 0 ");
    	$userS = array();
    	foreach ($userL as $userI){
    		$userS[$userI->id] = $userI->showname;
    	}
    	$userList = $formM->getElement("user");
    	$userList->setMultiOptions($userS);
    	
    	if($this->getRequest()->isPost()){
	    	$user 	= intval($this->getRequest()->getParam("user",0));
	    	$note 	= $this->getRequest()->getParam("note",0);
	    	
	    	$formM->isValid($this->getRequest()->getPost());
	    	
	    	$redata = array(
	    		"status" => 0,
	    		"msg"	 => "错误",
	    		"form"	 => $formM->render()
	    	);
	    	
	    	if($this->_user->type != 0){
	    		$redata["msg"] = "sorry，您没有此权限";
	    		$this->_helper->json($redata);
	    	}
	    	
	    	if($id != 0){    		
	        	$mailinboxM = new Application_Model_DbTable_Mailinbox();
	    		$data = array(
	    			"user" => $user,
	    			"note" => $note
	    		);
	    		try{
		    		if($mailinboxM->update($data, " `id` = {$id} ")){
		    			$redata["status"] = 1;
		    			$redata["msg"] = "成功";
		    			
		    			$msg = $mailinboxM->fetchRow(" `id` = {$id} ");
						$msg = $msg["subject"];
		    			Application_Service_Msg::write(
			        		"{$this->_user_name} 分配给你一封邮件：{$msg}",
			        		Application_Model_Msg::TYPE_MSG,
			        		$this->_user_id,
			        		$user
			        	);
		    		}else{
		    			$redata["msg"] = "修改失败！";
		    		}
	    		}catch (Exception $e){
	    			$redata["msg"] = "数据库错误 ： " . $e->getMessage();
	    		}
	    	}else {
	    		$redata["msg"] = "参数错误！";
	    	}
	    	$this->_helper->json($redata);
    	}else{    		
    		$mailId   = $formM->getElement("id");
    		$mailId->setValue($id);	
    		$this->view->form = $formM;
    		
	        $this->_helper->layout()->disableLayout();
	        $this->renderScript("zendform.phtml");
        }
    }
  
    /**
     * 设置为待回收状态
     */
    public function setdeletedAction()
    {
    	if($this->getRequest()->isPost()){
	    	$id 	= intval($this->getRequest()->getParam("id",0));
	    	
	    	$redata = array(
	    		"status" => 0,
	    		"msg"	 => "错误"
	    	);
	    	
	    	if($id != 0){    		
	        	$userM = new Application_Model_DbTable_Mailinbox();
	    		$data = array(
	    			"deleted" => 1
	    		);
	    		try{
		    		if($userM->update($data, " `id` = {$id} ")){
		    			$redata["status"] = 1;
		    			$redata["msg"] = "成功";
		    		}else{
		    			$redata["msg"] = "修改失败！";
		    		}
	    		}catch (Exception $e){
	    			$redata["msg"] = "数据库错误 ： " . $e->getMessage();
	    		}
	    	}else {
	    		$redata["msg"] = "参数错误！";
	    	}
	    	$this->_helper->json($redata);
    	}else{
    		die("404");
    	}
    	
    	
    }
     
    /**
     * 回收
     */
    public function recycleAction()
    {
    	if($this->getRequest()->isPost()){
	    	$id 	= intval($this->getRequest()->getParam("id",0));
	    	
	    	$redata = array(
	    		"status" => 0,
	    		"msg"	 => "错误"
	    	);
	    	
	    	if($id != 0){    		
	        	$userM = new Application_Model_DbTable_Mailinbox();
	    		$data = array(
	    			"deleted" => 0
	    		);
	    		try{
		    		if($userM->update($data, " `id` = {$id} ")){
		    			$redata["status"] = 1;
		    			$redata["msg"] = "成功";
		    		}else{
		    			$redata["msg"] = "修改失败！";
		    		}
	    		}catch (Exception $e){
	    			$redata["msg"] = "数据库错误 ： " . $e->getMessage();
	    		}
	    	}else {
	    		$redata["msg"] = "参数错误！";
	    	}
	    	$this->_helper->json($redata);
    	}else{
    		die("404");
    	}
    	
    	
    }
       
    /**
     * 发邮件
     * @see LoginController::indexAction()
     */
    public function addAction()
    {
    	$formM = new Application_Form_Base("mail");
    	$mailM = new Application_Model_DbTable_Mailoutbox();
    	
    	if($this->getRequest()->isPost()){
    		//邮件id
    		$data = $this->getRequest()->getParams();
    		$id = intval($data["id"]);

    		if($formM->isValid($data)){
        		$data  = $formM->getValues();         		
        		$data['create_user'] = $this->_user_id;   //创建人id
	        	$data['create_time'] = time();            //创建时间
	        	
	        	$result = NULL;
	    		if($id == 0){
	    			$result = $mailM->insert($data);
	    		}else {
	    			$result = $mailM->update($data, " `id`={$id} ");
	    		}
	    		
	    		if($this->getRequest()->isXmlHttpRequest()){
	    			$reData = array();
	    			$reData["status"] = $result?1:0;
	    			$reData["msg"]	  = $result?"成功":"失败";
	    			$this->_helper->json($reData);
	    		}else {
	    			$this->view->editeStatus = $data["edite_status"];
	    			$this->view->saved = TRUE;
	    			$this->renderScript("mail/addok.phtml");
	    		}
    		}else {
    			$reData = array();
    			$reData["status"] = $result?1:0;
        		$reData["msg"]="表单填写有误！";
        		$reData["form"] = $formM->getErrorMessages();
        		
    			if($this->getRequest()->isXmlHttpRequest()){
	    			$this->_helper->json($reData);
	    		}else {
	    			$this->view->error = $reData;
	    			//$this->renderScript("mail/sendok.phtml");
	    		}
        	}
        }else{
        	//获取表单页面
        	$userM = new Application_Model_DbTable_User();
        	$userInfo = $userM->fetchRow(" `id`={$this->_user_id} ");
        	$id = $mailM->insert(array());
        	$formM->clearAllDecorators();
        	if($userInfo)
        		$formM->getElement("from")->setValue($userInfo->email);
        	else 
        		$formM->getElement("from")->setAttrib("readonly", FALSE);
        		
        	$formM->getElement("id")->setValue($id);
        	$this->view->title = "写信";
    		$this->view->form = $formM;
        }
    }
    
    /**
     * 删除临时邮件
     */
    public function deltempmailAction(){}
    
	/**
	 * 删除
	 */
	public function delAction()
	{
		$reData = array(
			"status" => 0,
			"msg"    => "参数错误"
		);	    
    	$id = (array)$this->getRequest()->getParam('id');
    	if($id){
			$mailinboxM = new Application_Model_DbTable_Mailinbox();
			$where = $mailinboxM->getAdapter()->quoteInto('`id` IN(?)', $id);
			$mails = $mailinboxM->fetchAll($where);
			$mails = $mails->toArray();
			$msg = "";
			foreach ($mails as $mail){
				//组装系统消息体
				$msg .= "[{$mail["subject"]}],";
				//删除邮件文件
				@unlink(APPLICATION_PATH . "/.." . $mail["maildir"]);
			}			
    		if($result = $mailinboxM->delete($where)){
    			$reData = array(
					"status" => 1,
    		 		"msg"    => "成功删除{$result}条数据！"
    		 	);
    		 	$id = implode(",",$id);
    		 	Application_Service_Msg::write(
	        		"{$this->_user_name} 彻底删除邮件：{$msg}",
	        		Application_Model_Msg::TYPE_USERDO_LOG
	        	);
    		 }
	    }else{
	        	
	    }
	    $this->_helper->json($reData);
   }

	/**
	 * 阅读邮件 参数  [文件夹类型（boxtype）[inbox|outbox] , 邮件id（id）] | [邮件唯一标识（msgid）]
	 * 
	 * @throws Zend_Controller_Response_Exception
	 */
	public function viewmailAction()
	{
		$id = intval($this->getRequest()->getParam("id"));		//邮件id
		$boxType = $this->getRequest()->getParam("boxtype");	//文件夹类型		
		$msgId = $this->getRequest()->getParam("msgid");		//邮件的唯一标识，又有最高优先权
		
		if(empty($msgId)){
			if (empty($id) || empty($boxType)){
				die("参数错误");
				throw new Zend_Controller_Response_Exception();
			}else {
				if($boxType == "inbox"){
					$boxM = new Application_Model_DbTable_Mailinbox();
					try {
						$this->view->mail = $boxM->viewMailById($id);
					}catch (Exception $e){
						die($e->getMessage());
					}
				}else {
					$boxM = new Application_Model_DbTable_Mailoutbox();
					$this->view->mail = $boxM->viewMailById($id);
				}
			}
		}else {
			
		}
		
		$this->view->mailid = $id;
	}
	
	/**
	 * 获取（下载）附件
	 * @throws Zend_Controller_Response_Exception
	 */
	public function getattachmentAction()
	{
		$id  	 = intval($this->getRequest()->getParam("id"));		//邮件id
		$boxType = $this->getRequest()->getParam("boxtype");			//文件夹类型		
		$pid 	 = intval($this->getRequest()->getParam("partid"));		//附件id
		
		if($boxType == "inbox"){
			$boxM = new Application_Model_DbTable_Mailinbox();
		}else {
			$boxM = new Application_Model_DbTable_Mailoutbox();
		}
		$mail = $boxM->fetchRow(" `id`={$id} ");
		if($mail && $mailPath = $mail->maildir){
			$id = $mail->id;
			$mailPath = APPLICATION_PATH . '/..' . $mailPath;
			if(file_exists($mailPath)){
				Application_Service_Mail::downloadAttachment($mailPath,$pid);
				die(0);
			}else {
				die("没有找到邮件文件 {$mailPath}，它可能已经被删除");
				throw new Zend_Controller_Response_Exception();
			}
		}else{
			die("没有找到邮件");
			throw new Zend_Controller_Response_Exception();
		}		
	}

	/**
	 * 停止收件
	 */
	public function onStopReciveMail()
	{
		try {
			$flagFile = $this->_appconf->cachePath . "mailreciver.temp";
			@unlink($flagFile);
		}catch (Exception $e){}		
	}
	
	/**
	 * 当开始的时候
	 * @throws Exception
	 */
	public function onStartReciveMail()
	{		
		//标识文件路径
		$flagFile = $this->_appconf->cachePath . "mailreciver.temp";
		$stopFile = $this->_appconf->cachePath . "mailreciverStop.temp";		
	}
	
	/**
	 * 统一收件
	 */
	public function recivemailAction()
	{
		//是否强制执行
		$EnforcementRun = $this->getRequest()->getParam("EnforcementRun",FALSE);
		//是否强制停止，强制重启需要客户端配合。
		$EnforcementStop = $this->getRequest()->getParam("EnforcementStop",FALSE);
		//是否是子进程
		$isChildProcess  = $this->getRequest()->getParam("isChildProcess",FALSE);

		//标识文件路径
		$flagFile = $this->_appconf->cachePath . "mailreciver.temp";
		$stopFile = $this->_appconf->cachePath . "mailreciverStop.temp";
		
		//强制停止，停止所有收件进程。
		if ($EnforcementStop){
			@file_put_contents($stopFile, time());
			$this->onStopReciveMail();
			die();
		}
		
		//强制启动，可能会启动两个以上进程收邮件
		if($EnforcementRun){
			@file_put_contents($stopFile, "");
		}
		
		//告诉浏览器别等了
		if(!$isChildProcess){
			try {
				//永不超时
				set_time_limit(0);
				$client = new Zend_Http_Client($this->view->pagePath . "/mail/recivemail/isChildProcess/1");
				/*foreach ($_COOKIE as $k=>$v){
					$client->setCookie($k,$v);
				}*/
				$client->setConfig(array(
					"timeout" => 1
				));
				$T = $client->request();
			}catch (Exception $e){
				
			}
			die("OK");
		}
		/*@register_shutdown_function(array(
			$this,
			"onStartReciveMail"
		));	*/
		
		if(!is_readable($this->_appconf->cachePath) ){
			throw new Exception("缓存目录：".$appconf->cachePath." 或文件:{$flagFile}  不可写，请检查它是否存在和是否可写。");
			die();//无用，安心
		}
		if($flag = file_get_contents($flagFile)){
			if(time() - intval($flag) < 3600*1){
				//如果已经有实例在运行，或者程序距离上次运还没有过去1h，那就停止运行。
				die("PROGAME HAS BEEN RUNED !");
			}
		}else{
			//永不超时
			set_time_limit(0);
			//意外退出时，杀掉标识文件
			@register_shutdown_function(array(
				$this,
				"onStopReciveMail"
			));
			@ignore_user_abort(TRUE);
		}
		
		$mailSM = Application_Service_Mail::getInstance();
    	$mailcM= new Application_Model_DbTable_Mailconf();
    	
		while (TRUE){
			//如果停止位文件被标记，则停止
			if ($stopFlag = file_get_contents($stopFile)){
				break;
			}
			
			//如果没有则记录运行时间
			$startTime = microtime();
			@file_put_contents($flagFile, time());
			
			//开始干活
	    	$mailc = $mailcM->fetchAll(" 1=1 ");
	    	foreach ($mailc as $conf){
	    		if($conf)
	    			$mailSM->setReadConf($conf->toArray());
	    			$mailSM->reciveMail();
	    	}
	    	@file_put_contents($this->_appconf->logoPath . "mail.log",date("Y-m-d H:i:s",time()) . " RECIVE OVER USER TIME " . ($startTime - microtime())."\n",FILE_APPEND);
	    	@ob_clean();
	    	//输出
	    	ob_flush();
			flush();
			ob_end_flush();
	    	
	    	//休息1分钟
	    	sleep(60);
		}
		die();
	}

	/**
	 * 当停止发件
	 */
	public function onStopSendMail()
	{
		try {
			$flagFile = $this->_appconf->cachePath . "mailsender.temp";
			@unlink($flagFile);
		}catch (Exception $e){}	
	}
	
	/**
	 * 当开始发件
	 */
	public function onStartSendMail()
	{
		
	}
	/**
	 * 统一发件
	 */
	public function sendmailAction()
	{
		//是否强制执行
		$EnforcementRun = $this->getRequest()->getParam("EnforcementRun",FALSE);
		//是否强制停止，强制重启需要客户端配合。
		$EnforcementStop = $this->getRequest()->getParam("EnforcementStop",FALSE);
		//是否是子进程
		$isChildProcess  = $this->getRequest()->getParam("isChildProcess",FALSE);
		
		//标识文件路径
		$flagFile = $this->_appconf->cachePath . "mailsender.temp";
		$stopFile = $this->_appconf->cachePath . "mailsenderStop.temp";
		
		//强制停止，停止所有收件进程。
		if ($EnforcementStop){
			@file_put_contents($stopFile, time());
			$this->onStopReciveMail();
			die("WAITING FOR STOPING...");
		}
	
		//强制启动，可能会启动两个以上进程
		if($EnforcementRun){
			@file_put_contents($stopFile, "");
		}
		
		//启动新进程并告诉浏览器别等了
		if(!$isChildProcess){
			try {
				//永不超时
				set_time_limit(0);
				$client = new Zend_Http_Client($this->view->pagePath . "/mail/sendmail/isChildProcess/1");
				$client->setConfig(array(
					"timeout" => 1
				));
				$T = $client->request();
			}catch (Exception $e){}
			die("OK");
		}
		
		//检查标记位权限
		if(!is_readable($this->_appconf->cachePath) ){
			$msg = "缓存目录：".$appconf->cachePath." 或文件:{$flagFile}  不可写，请检查它是否存在和是否可写。";
			Application_Service_Msg::write(
				$msg,
				Application_Model_Msg::TYPE_SYS_LOG				
			);
			throw new Exception($msg);
			die();//无用，安心
		}
		
		//检查启动条件
		if($flag = file_get_contents($flagFile)){
			if(time() - intval($flag) < 3600*1){
				//如果已经有实例在运行，或者程序距离上次运还没有过去1h，那就停止运行。
				die("PROGAME HAS BEEN RUNED !");
			}
		}else{
			//永不超时
			set_time_limit(0);
			//意外退出时，杀掉标识文件
			@register_shutdown_function(array(
				$this,
				"onStopSendMail"
			));
			@ignore_user_abort(TRUE);
		}
		
		$mailSM = Application_Service_Mail::getInstance();
		$mailcM= new Application_Model_DbTable_Mailconf();		
		$mailOutBoxM = new Application_Model_DbTable_Mailoutbox();

		while (TRUE){
			$startTime = microtime();
			@file_put_contents($flagFile, time());
			
			//如果停止位文件被标记，则停止
			if ($stopFlag = file_get_contents($stopFile)){
				break;
			}
			
			//查出未发送的邮件
			$select = $mailOutBoxM->select();
			$select->where(" `state_send`<1 ");
			$select->where(" `approve_status`=1 ");
			$select->where(" `edite_status`=1 ");
			$select->where(" `deleted`=0 ");
			$mailArr = $mailOutBoxM->fetchAll($select);
			
			//循环发送他们
			foreach ($mailArr as $mail){
				try {
					if(!empty($mail->from)){
						//查出对应发送器（账户）的配置
						$select = $mailcM->select();
						$select->where(" `email` = ?",$mail->from);
						$sender = $mailcM->fetchRow($select);
						if($sender){
							$sender = $sender->toArray();
							//配置账户
							$mailSM->setSenderConf($sender);
							//发送成功后标记为已发送
							if ($mailSM->sendMail($mail)){
								$data = array(
									"state_send" => 1
								);
								$mailOutBoxM->update($data, " `id` = {$mail->id}");
								echo $mail->id,"\n";
							};
						}
					}
				} catch (Exception $e) {
					//出错继续
					echo "error\n",$e->getMessage();
					//throw $e;
				}			
			}
			
			@file_put_contents($this->_appconf->logoPath . "mail.log",date("Y-m-d H:i:s",time()) . " SEND OVER USER TIME " . ($startTime - microtime())."\n",FILE_APPEND);
	    	@ob_clean();
	    	//输出
	    	ob_flush();
			flush();
			ob_end_flush();
			
	    	//休息1分钟
	    	sleep(60);
		}
    	die();
	}
	
	/**
	 * 匹配全部客户邮件
	 */
	public function matchcustomerAction()
	{
		$mailM = new Application_Model_Mail();
		$mailM->matchCustomer();
		$data = array(
			"status" => 1,
			"msg" 	 => "ok"
		);
		$this->_helper->json($data);
	}
}

